package com.yiwu.web.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.yiwu.common.aspect.ApiOperationLog;
import com.yiwu.common.domain.dto.UserDTO;
import com.yiwu.common.domain.dto.UserDetailInfoDTO;
import com.yiwu.common.domain.dto.UserInfoDTO;
import com.yiwu.common.domain.entity.Products;
import com.yiwu.common.domain.entity.UserFavorites;
import com.yiwu.common.domain.entity.Users;
import com.yiwu.common.enums.ResponseCode;
import com.yiwu.common.exception.BaseResponse;
import com.yiwu.common.exception.BusinessException;
import com.yiwu.common.model.vo.user.UserCodeReqVO;
import com.yiwu.common.utils.EncryptionUtil;
import com.yiwu.common.utils.IpUtil;
import com.yiwu.common.utils.ResultUtil;
import com.yiwu.web.service.UserService;
import io.netty.util.internal.StringUtil;
import io.swagger.v3.oas.annotations.Operation;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.validation.constraints.NotNull;
import lombok.extern.slf4j.Slf4j;
import org.apache.logging.log4j.util.Strings;
import org.redisson.api.RRateLimiter;
import org.redisson.api.RateIntervalUnit;
import org.redisson.api.RateType;
import org.redisson.api.RedissonClient;
import org.springframework.beans.BeanUtils;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.bind.annotation.*;

import java.util.concurrent.TimeUnit;

import static com.yiwu.common.utils.EncryptionUtil.getUserToken;

/**
 * @version 1.0
 * @description TODO
 * @date 2024/5/22 22:28
 */
@Slf4j
@RestController
@RequestMapping("/user")
public class UserController {

    @Resource
    private UserService userService;
    @Resource
    private StringRedisTemplate stringRedisTemplate;

    @Resource
    RedissonClient redissonClient;

    @ApiOperationLog
    @Operation(summary = "登录")
    @PostMapping("/login")
    public BaseResponse<UserDTO> login(@RequestBody UserCodeReqVO userCodeReqVO, HttpServletRequest httpServletRequest) {
//        String ipAddress = IpUtil.getIpAddress(httpServletRequest);
//        String black_key = "LOGIN_BLACK";
//        String white_key = "LOGIN_WHITE";
//        if (Boolean.FALSE.equals(stringRedisTemplate.opsForSet().isMember(white_key, ipAddress))) {
//            if (Boolean.TRUE.equals(stringRedisTemplate.opsForSet().isMember(black_key, "*"))) {
//                return ResultUtil.fail(ResponseCode.SYSTEM_ERROR, "系统升级中，禁止所有用户访问");
//            }
//            if (Boolean.TRUE.equals(stringRedisTemplate.opsForSet().isMember(black_key, ipAddress))) {
//                log.info("BlackUser:" + ipAddress);
//                return ResultUtil.fail(ResponseCode.SYSTEM_ERROR, "您已经被系统列为黑名单");
//            }
//            String key = "LOGIN_" + ipAddress;
//            String all_key = "LOGIN_ALL";
//            RRateLimiter rateLimiter = redissonClient.getRateLimiter(key);
//            rateLimiter.trySetRate(RateType.OVERALL, 5, 1, RateIntervalUnit.DAYS);
//            RRateLimiter rateLimiterAll = redissonClient.getRateLimiter(all_key);
//            rateLimiterAll.trySetRate(RateType.OVERALL, 6, 1, RateIntervalUnit.DAYS);
//            if (!rateLimiter.tryAcquire()) {
//                stringRedisTemplate.opsForSet().add(black_key, ipAddress);
//                return ResultUtil.fail(ResponseCode.SYSTEM_ERROR, "单位时间请求过多，已被加入黑名单");
//            }
//            if (!rateLimiterAll.tryAcquire()) {
//                stringRedisTemplate.opsForSet().add(black_key, "*");
//                return ResultUtil.fail(ResponseCode.SYSTEM_ERROR, "系统正在升级中,请等待");
//            }
//        }
        UserDTO weiXinPhoneResponse = userService.login(userCodeReqVO);
        return ResultUtil.success(weiXinPhoneResponse);
    }

    @Operation(summary = "测试登录")
    @PostMapping("/loginl")
    public BaseResponse<UserDTO> login() {
        String phone = "18682851589";
        Users user = new Users();
        Users users = user.insertOrLogin(phone);
        UserDTO userDTO = new UserDTO();
        BeanUtils.copyProperties(users, userDTO);
        Long userId = users.getId();
        userDTO.setId(userId.toString());
        String encrypt = EncryptionUtil.encrypt(userDTO.getId());
        userDTO.setToken(encrypt);


        QueryWrapper<UserFavorites> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("user_id", userId);
        UserFavorites userFavorites = new UserFavorites();
        Long favoriteCount = userFavorites.selectCount(queryWrapper);
        QueryWrapper<Products> productsQueryWrapper = new QueryWrapper<>();
        productsQueryWrapper.eq("seller_id", userId);
        productsQueryWrapper.eq("pstatus", 0);
        Products products = new Products();
        Long productCount = products.selectCount(productsQueryWrapper);

        userDTO.setFavoriteCount(favoriteCount);
        userDTO.setProductCount(productCount);

        stringRedisTemplate.opsForValue().set(userId + "yiwu-favoriteCount", favoriteCount.toString(), 7, TimeUnit.DAYS);
        stringRedisTemplate.opsForValue().set(userId + "yiwu-productCount", productCount.toString(), 7, TimeUnit.DAYS);
        stringRedisTemplate.opsForValue().set(encrypt + "yiwu", userId.toString(), 7, TimeUnit.DAYS);

        return ResultUtil.success(userDTO);
    }

    @Operation(summary = "测试登录2")
    @PostMapping("/loginl2")
    public BaseResponse<UserDTO> login2() {
        String phone = "18682851510";
        Users user = new Users();
        Users users = user.insertOrLogin(phone);
        UserDTO userDTO = new UserDTO();
        BeanUtils.copyProperties(users, userDTO);
        Long userId = users.getId();
        userDTO.setId(userId.toString());
        String encrypt = EncryptionUtil.encrypt(userDTO.getId());
        userDTO.setToken(encrypt);


        QueryWrapper<UserFavorites> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("user_id", userId);
        UserFavorites userFavorites = new UserFavorites();
        Long favoriteCount = userFavorites.selectCount(queryWrapper);
        QueryWrapper<Products> productsQueryWrapper = new QueryWrapper<>();
        productsQueryWrapper.eq("seller_id", userId);
        productsQueryWrapper.eq("pstatus", 0);
        Products products = new Products();
        Long productCount = products.selectCount(productsQueryWrapper);

        userDTO.setFavoriteCount(favoriteCount);
        userDTO.setProductCount(productCount);

        stringRedisTemplate.opsForValue().set(userId + "yiwu-favoriteCount", favoriteCount.toString(), 7, TimeUnit.DAYS);
        stringRedisTemplate.opsForValue().set(userId + "yiwu-productCount", productCount.toString(), 7, TimeUnit.DAYS);
        stringRedisTemplate.opsForValue().set(encrypt + "yiwu", userId.toString(), 7, TimeUnit.DAYS);

        return ResultUtil.success(userDTO);
    }

    @Operation(summary = "测试登录3")
    @PostMapping("/loginl3")
    public BaseResponse<UserDTO> login3() {
        String phone = "18682811111";
        Users user = new Users();
        Users users = user.insertOrLogin(phone);
        UserDTO userDTO = new UserDTO();
        BeanUtils.copyProperties(users, userDTO);
        Long userId = users.getId();
        userDTO.setId(userId.toString());
        String encrypt = EncryptionUtil.encrypt(userDTO.getId());
        userDTO.setToken(encrypt);


        QueryWrapper<UserFavorites> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("user_id", userId);
        UserFavorites userFavorites = new UserFavorites();
        Long favoriteCount = userFavorites.selectCount(queryWrapper);
        QueryWrapper<Products> productsQueryWrapper = new QueryWrapper<>();
        productsQueryWrapper.eq("seller_id", userId);
        productsQueryWrapper.eq("pstatus", 0);
        Products products = new Products();
        Long productCount = products.selectCount(productsQueryWrapper);

        userDTO.setFavoriteCount(favoriteCount);
        userDTO.setProductCount(productCount);

        stringRedisTemplate.opsForValue().set(userId + "yiwu-favoriteCount", favoriteCount.toString(), 7, TimeUnit.DAYS);
        stringRedisTemplate.opsForValue().set(userId + "yiwu-productCount", productCount.toString(), 7, TimeUnit.DAYS);
        stringRedisTemplate.opsForValue().set(encrypt + "yiwu", userId.toString(), 7, TimeUnit.DAYS);

        return ResultUtil.success(userDTO);
    }

    @Operation(summary = "获取个人发布和收藏数量")
    @GetMapping("/get")
    public BaseResponse<UserInfoDTO> getUserInfo(HttpServletRequest request) {
        Long userId = getUserToken(request);
        String favoriteCount = stringRedisTemplate.opsForValue().get(userId + "yiwu-favoriteCount");
        String productCount = stringRedisTemplate.opsForValue().get(userId + "yiwu-productCount");

        UserInfoDTO userInfoDTO = new UserInfoDTO();
        userInfoDTO.setFavoriteCount(favoriteCount != null ? Integer.parseInt(favoriteCount) : 0);
        userInfoDTO.setProductCount(productCount != null ? Integer.parseInt(productCount) : 0);

        return ResultUtil.success(userInfoDTO);
    }

    @Operation(summary = "获取用户信息详情")
    @GetMapping("/info")
    public BaseResponse<UserDetailInfoDTO> getUser(@RequestParam @NotNull String userId) {
        Users users = new Users();
        users.selectById(userId);
        UserDetailInfoDTO userDetailInfoDTO = new UserDetailInfoDTO();
        BeanUtils.copyProperties(users, userDetailInfoDTO);
        userDetailInfoDTO.setId(users.getId().toString());
        userDetailInfoDTO.setLastOffTime(users.getLastOffTime().toString());
        return ResultUtil.success(userDetailInfoDTO);
    }

    @Operation(summary = "编辑个人资料")
    @PostMapping("/update/info")
    public BaseResponse<Boolean> updateUserInfo(@RequestBody UserDetailInfoDTO userDetailInfoDTO, HttpServletRequest request) {
        Long userId = getUserToken(request);
        if (Strings.isNotEmpty(userDetailInfoDTO.getId()) && Long.parseLong(userDetailInfoDTO.getId()) != userId) {
            throw new BusinessException(ResponseCode.PARAMETER_ERROR);
        }
        String userName = userDetailInfoDTO.getUserName();
        String school = userDetailInfoDTO.getSchool();
        String avatarUrl = userDetailInfoDTO.getAvatarUrl();

        if (Strings.isEmpty(userName) || Strings.isEmpty(school) || Strings.isEmpty(avatarUrl)) {
            throw new BusinessException(ResponseCode.PARAMETER_ERROR);
        }
        Users user = new Users();
        BeanUtils.copyProperties(userDetailInfoDTO, user);
        user.setId(Long.valueOf(userDetailInfoDTO.getId()));
        user.setLastOffTime(System.currentTimeMillis());
        boolean flag = user.updateById();
        return ResultUtil.success(flag);
    }

    //todo 用户退出


}
